package com.atguigu.tree;

import java.util.Arrays;

/**
 * description:
 * Created by 才睡醒 on 2021-07-23
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {4, 6, 8, 5, 9};
        int temp = 0;
        //将无序序列构建成一个堆，根据升序降序需求选择大顶堆或者小顶堆
        for (int i = arr.length /2 -1 ; i >=0 ; i--) {
            adjustHeap(arr,i,arr.length);
        }
        //将堆顶元素与末尾元素交换，将最大元素沉到数组末端
        //重新调整结构，使其满足堆定义，然后继续交换堆顶元素与当前末尾元素，反复执行调整+交换步骤，直到整个序列有序。
        for (int j = arr.length-1; j >0 ; j--) {
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr,0,j);
        }
        System.out.println(Arrays.toString(arr));
    }

    //编写一个堆排序的方法
    public static void headSort(int arr[]) {
        System.out.println("堆排序！");

    }




    /**
     * 功能: 完成将以i 对应的非叶子结点的树调整成大顶堆
     *
     * @param arr    待调整的数组
     * @param i      表示非叶子结点在数组中索引
     * @param length 表示对多少个元素继续调整，length是在逐渐的减少
     */
    //将一个数组（二叉树），调整成一个大顶堆
    public static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];//先取出当前元素的值，保存在临时变量
        //开始调整
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            if( k+1 < length && arr[k] < arr[k+1]){ //说明左子节点的值小于右子结点
                k++;//k 指向右子结点
            }
            if(arr[k] > temp){ //如果子节点大于父节点
                arr[i] = arr[k];  //把较大的值赋给当前节点
                i = k ;  //!!! i 指向k，继续循环比较
            }else {
                break;//
            }
        }
        //当for循环结束后，我们已经将以i为父结点的最大值,放在了最顶（局部）
        arr[i] = temp;
    }
}
